const config = require('config')
const tool = require('./src/commons/tool')

require('./src/commons/custom_fmt_log').overwrite(console) // 重写一下console

// 启动MQTT服务
const mqttService = require('./src/services/mqtt')

async function startUp() {
    // 启动MQ
    // mqttService.startMqtt();
    const mongoose_service = [ //,require('./src/services/schedule'),
        require('./src/services/mongoose')
    ]
    await Promise.all(tool.runMethodByName(mongoose_service, 'lift'))

}
/**
 * 监听 http 服务
 */
async function listenHttpServer() {

    const http = require('http')
    const app = require('./src')
    //读取配置文件得到port参数
    const { port } = config.get('Customer.initConfig')
    const httpServer = http.createServer(app.callback());
    return new Promise((resolve, reject) => {
        httpServer.once('error', (error) => {  
            reject(error); // 当服务器发生错误时，拒绝 Promise  
        });  
      
        httpServer.listen(port, () => {  
            console.info(`http server is running at http://0.0.0.0:${port}`);  
            resolve(); // 当服务器成功启动时，解决 Promise  
            // 注意：这里不应该有 SIGINT，它不是一个应该传递给 resolve() 的参数  
        }); 
    })

}

/**
 * 监听进程关闭回调 执行一些业务逻辑清理
 */
async function listenShutdown() {
    const beforeShutdown = async () => {
        const mongoose_service = [
            require('./src/services/mongoose')
        ]
        await Promise.all(tool.runMethodByName(mongoose_service, 'lower'));

    }
    process.on('SIGINT', async () => {
        console.info('Shutting down...')
        let startTime = Date.now()

        let err
        try {
            // mqttService.closeMqtt()
            await beforeShutdown()
            console.info(`Shuted down...(in ${Date.now() - startTime}ms)`)
        }
        catch (e) {
            err = e
        }
        process.nextTick(() => {
            if (err) {
                console.error(err)
            }
            process.exit(err ? 1 : 0)
        })
    })
}


/**
* 总启动入口
* 执行步骤：
* 1、启动一些预启动的服务（数据库初始化，定时脚本、数据初始化）
* 2、监听端口 开始接受客户端的请求
* 3、监听关闭回调
*/
async function run() {
    function preload() {
        process.on('uncaughtException', (err) => {
            // eslint-disable-next-line no-console
            console.error('uncaughtException:', err)
            process.exit(1)
        })

        process.on('unhandledRejection', (reason, p) => {
            // eslint-disable-next-line no-console
            console.log('Unhandled Rejection at:', p, 'reason:', reason)
            process.exit(1)
        })
    }

    preload()
    const { serverName } = config.get('Customer.initConfig')
    console.info(`==============${serverName} start===============`)
    console.info(`==============NODE_ENV:${process.env.NODE_ENV}==============`)
    console.time('serverRunTime')
    await startUp()
    await listenHttpServer()
    await listenShutdown()
    console.timeEnd('serverRunTime')
}


//   启动

run().catch((e) => {
    console.error('server run', e)
    process.exit(1)
})

